/*
 * ECARX Technology Limited is the owner of the copyright and the trade secret of this software.
 * Without permission, no one has the right to obtain, disclose or use this software in any way.
 */
package com.ecarx.systemui.plugin.psd;

import android.content.Context;
import android.graphics.PixelFormat;
import android.hardware.display.DisplayManager;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;

import com.ecarx.systemui.plugin.R;
import com.ecarx.systemui.plugin.utils.LogUtils;
import com.ecarx.systemui.plugin.PluginContext;

public class PsdBarsManager {

    private static final String TAG = "PsdBarsManager";

    private WindowManager mWindowManager;
    private DisplayManager mDisplayManager;
    private Context mContext;
//    private Handler mHandler;

    private PsdNavigationBarView psdNavigationBarView;
    private PsdStatusBarView psdStatusBarView;

    public enum ESystemBarType {
        STATUS_BAR,
        NAVIGATION_BAR,
        SYSTEM_BARS;
    }

    private static class HOLDER {
        private static final PsdBarsManager INSTANCE = new PsdBarsManager();
    }

    public static PsdBarsManager getInstance() {
        return HOLDER.INSTANCE;
    }

    private PsdBarsManager() {
        mContext = PluginContext.getInstance().getPluginContext();
//        mHandler = startHandlerThread();
        mDisplayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);

    }

    public void start() {
        if (mDisplayManager == null) {
            return;
        }

        mDisplayManager.registerDisplayListener(new DisplayManager.DisplayListener() {
            @Override
            public void onDisplayAdded(int displayId) {
                LogUtils.d(TAG, "onDisplayAdded:" + displayId);
                showPsdBars(ESystemBarType.NAVIGATION_BAR);
            }

            @Override
            public void onDisplayRemoved(int displayId) {
                LogUtils.d(TAG, "onDisplayRemoved:" + displayId);
                removePsdBars(ESystemBarType.NAVIGATION_BAR);
            }

            @Override
            public void onDisplayChanged(int displayId) {
                LogUtils.d(TAG, "onDisplayChanged:" + displayId);
                removePsdBars(ESystemBarType.NAVIGATION_BAR);
                showPsdBars(ESystemBarType.NAVIGATION_BAR);
            }
        }, null);
    }


//    private Handler startHandlerThread() {
//        HandlerThread thread = new HandlerThread("ScreenDecorations");
//        thread.start();
//        return thread.getThreadHandler();
//    }

    private PsdStatusBarView initStatusBar() {
        View statusBarView = LayoutInflater.from(mContext).inflate(R.layout.psd_status_bar_layout, null, false);

        if (statusBarView instanceof PsdStatusBarView) {
            return (PsdStatusBarView) statusBarView;
        }
        return null;
    }


    public void showPsdBars(ESystemBarType type) {
        switch (type) {
            case STATUS_BAR:
                addView(getPsdStatusBarView(), getPsdStatusBarLayoutParams());
                break;
            case NAVIGATION_BAR:
                addView(getPsdNavigationBarView(), getPsdNavigationBarLayoutParams());
                break;
            case SYSTEM_BARS:
                addView(getPsdStatusBarView(), getPsdStatusBarLayoutParams());
                addView(getPsdNavigationBarView(), getPsdNavigationBarLayoutParams());
                break;
            default:
                break;
        }
    }


    public void removePsdBars(ESystemBarType type) {
        if (mWindowManager == null) {
            return;
        }
        switch (type) {
            case STATUS_BAR:
                mWindowManager.removeView(getPsdStatusBarView());
                break;
            case NAVIGATION_BAR:
                mWindowManager.removeView(getPsdNavigationBarView());
                break;
            case SYSTEM_BARS:
                mWindowManager.removeView(getPsdStatusBarView());
                mWindowManager.removeView(getPsdNavigationBarView());
                break;
            default:
                break;
        }
    }


    private PsdStatusBarView getPsdStatusBarView() {
        if (psdStatusBarView == null) {
            psdStatusBarView = initStatusBar();
        }
        return psdStatusBarView;
    }

    public WindowManager.LayoutParams getPsdStatusBarLayoutParams() {
        int windowType = getWindowType(true);

        int mStatusX = 0;
        int mStatusY = 60;
        int mStatusWindowWidth = WindowManager.LayoutParams.MATCH_PARENT;
        int mStatusWindowHeight = 60;

        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
        lp.type = windowType;
        lp.format = PixelFormat.TRANSLUCENT;

        lp.x = mStatusX;
        lp.y = mStatusY;
        lp.width = mStatusWindowWidth;
        lp.height = mStatusWindowHeight;
        lp.gravity = Gravity.START | Gravity.TOP;

        lp.flags = lp.flags
                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
        ;

        lp.packageName = mContext.getPackageName();
        return lp;
    }

    public PsdNavigationBarView getPsdNavigationBarView() {
        if (psdNavigationBarView == null) {
            psdNavigationBarView = new PsdNavigationBarView(mContext);
        }
        return psdNavigationBarView;
    }

    public WindowManager.LayoutParams getPsdNavigationBarLayoutParams() {

        int windowType = getWindowType(false);

        int mNavX = 0;
        int mNavY = 300;
        int mNavWindowWidth = WindowManager.LayoutParams.MATCH_PARENT;
        int mNavWindowHeight = 140;

        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
        lp.type = windowType;
        lp.format = PixelFormat.TRANSLUCENT;
        lp.setTitle("psdnavigationbar");

//        lp.x = mNavX;
//        lp.y = mNavY;
        lp.width = mNavWindowWidth;
        lp.height = mNavWindowHeight;
        lp.gravity = Gravity.START | Gravity.BOTTOM;

        lp.flags = lp.flags
                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
        ;

        lp.packageName = mContext.getPackageName();
        return lp;
    }

    private int getWindowType(boolean isStatus) {
//        int windowType = isStatus ? WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL :
//                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
//        if (windowType == 0) {
//            windowType = AdaptApiHelper.getWindowType(IWindowManagerPolicy.CODE_SWIPE_FROM_TOP_VIEW, 0);
//            LogUtils.d(TAG, "windowType from AdaptAPI:" + windowType);
//        }
//        LogUtils.d(TAG, "isStatus:" + isStatus + "  windowType:" + windowType);
//        return windowType;

//        return WindowManager.LayoutParams.TYPE_STATUS_BAR;
        return 2024;//WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL
    }


    private void addView(View view, WindowManager.LayoutParams layoutParams) {
        LogUtils.d(TAG, "addView:" + view + "  layoutParams:" + layoutParams);
        Display[] displays = mDisplayManager.getDisplays();
        LogUtils.d(TAG, "addView displays length:" + displays.length);
        for (Display display : displays) {
            LogUtils.d(TAG, "addView display id:" + display.getDisplayId() + display.getName());
            if (display.getDisplayId() != Display.DEFAULT_DISPLAY && display.getType() == Display.TYPE_INTERNAL) {
                Context displayContext = mContext.createDisplayContext(display);
                mWindowManager = (WindowManager) displayContext.getSystemService(Context.WINDOW_SERVICE);
                try {
                    if (view.getWindowToken() != null) {
                        mWindowManager.removeView(view);
                        LogUtils.d(TAG, "REMOVE! " + view + " in " + this);
                    }
                    mWindowManager.addView(view, layoutParams);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public Context getPSDContext() {
        Context displayContext = null;
        Display[] displays = mDisplayManager.getDisplays();
        LogUtils.d(TAG, "getPSDContext displays length:" + displays.length);
        for (Display display : displays) {
            LogUtils.d(TAG, "getPSDContext display id:" + display.getDisplayId() + display.getName());
            if (display.getDisplayId() != Display.DEFAULT_DISPLAY && display.getType() == Display.TYPE_INTERNAL) {
                displayContext = mContext.createDisplayContext(display);
            }
        }
        return displayContext;
    }
}
